﻿/*! @file
********************************************************************************
<PRE>
文 件 名    : BaseProjFile.cs
说    明    : 转换 项目文件 基类
作    者    : 汪泽然
--------------------------------------------------------------------------------
备    注    : 
--------------------------------------------------------------------------------
修改记录: 
 * 日    期    版  本    修改人    修改内容 
 * 2009-7-9    0.5.0     汪泽然    完成基本转换功能
</PRE>
********************************************************************************
* 版权所有(c) 2008 ~ 2009, 汪泽然, 保留所有权利
*******************************************************************************/
using System;
using System.Xml;
using System.Xml.XPath;
using System.Collections.Generic;
using Wangzeran.Transform.Core.TransformException;
using Wangzeran.Transform.Core.ITransform;

namespace Wangzeran.Transform.Core.Support
{
    /// <summary>
    /// 转换 项目文件 的基类
    /// </summary>
    public abstract class BaseProjFile : BaseChildFiles, ITransformFile
    {

        #region Common Variables

        /// <summary>
        /// 项目文件的XML命名空间
        /// </summary>
        protected const string COMMON_XMLNAMESPACE = 
                @"http://schemas.microsoft.com/developer/msbuild/2003";
        /// <summary>
        /// CSharp项目文件
        /// </summary>
        private const string TYPE_CSPROJ = ".csproj";

        #endregion


        #region Common Properties

        /// <summary>
        /// 当前的项目文件版本
        /// </summary>
        protected abstract string CURRENT_VERSION { get; }

        #endregion


        #region IBaseFile 成员

        /// <summary>
        /// 获取当前项目文件的版本信息
        /// </summary>
        /// <param name="filePath">文件完整路径</param>
        /// <returns></returns>
        /// <exception cref="UnGetVersionException">无法获取版本的异常</exception>
        public virtual string GetVersion(string filePath)
        {
            try
            {
                string version = "";

                XmlDocument doc = new XmlDocument();
                doc.Load(filePath);
                XPathNavigator nav = doc.CreateNavigator();
                XmlNamespaceManager manager = new XmlNamespaceManager(nav.NameTable);
                manager.AddNamespace("ms", COMMON_XMLNAMESPACE);

                // 从项目文件的xml格式中获取项目版本
                XPathNodeIterator iter =
                    nav.Select("/ms:Project/ms:PropertyGroup/ms:ProductVersion", manager);

                iter.MoveNext();
                version = iter.Current.Value;

                return version;
            }
            catch (Exception ex)
            {
                throw new UnGetVersionException(filePath, ex.Message);
            }
        }

        /// <summary>
        /// 检查当前文件的版本是否为当前版本
        /// 如果是，则不进行转换
        /// 如果否，则可以进行转换
        /// </summary>
        /// <param name="filePath">项目文件完整路径</param>
        /// <returns>True: 非当前版本 False:当前版本</returns>
        /// <exception cref="IsCurrentVersionException">当前文件版本已经是转换目标版本的异常</exception>
        /// <exception cref="UnGetVersionException">无法获取文件版本的异常</exception>
        public virtual bool IsDiffVersion(string filePath)
        {
            try
            {
                string version = GetVersion(filePath);

                if (version != CURRENT_VERSION)
                {
                    return true;
                }
                else
                {
                    throw new IsCurrentVersionException(filePath);
                }

            }
            catch (IsCurrentVersionException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                throw new UnGetVersionException(filePath, ex.Message);
            }
        }

        /// <summary>
        /// 转换项目文件
        /// </summary>
        /// <param name="filePath">项目文件完整路径</param>
        /// <returns>True：转换成功 False：转换失败</returns>
        /// <exception cref="TransformFailureException">转换失败的异常</exception>
        public virtual bool Transform(string filePath)
        {
            return false;
        }

        #endregion
        
    }
}
